package com.atom.annotation.api;


import com.atom.annotation.ApiImplNonNull;
import com.atom.annotation.ApiImplNullable;

import java.util.Collection;

public interface ApiImplContext {

    <T> Collection<Class<? extends T>> getApis(@ApiImplNonNull Class<T> requiredType);

    <T> void getApis(@ApiImplNonNull Class<T> requiredType, @ApiImplNonNull ApiImplCallback<Collection<Class<? extends T>>> callback);

    <T> Collection<Class<? extends T>> getApis(@ApiImplNonNull Class<T> requiredType, String name, boolean useRegex);

    <T> void getApis(@ApiImplNonNull Class<T> requiredType, String name, boolean useRegex, @ApiImplNonNull ApiImplCallback<Collection<Class<? extends T>>> callback);

    <T> Collection<Class<? extends T>> getApis(@ApiImplNonNull Class<T> requiredType, @ApiImplNonNull ApiCLassFilter<T> filter);

    <T> void getApis(@ApiImplNonNull Class<T> requiredType, @ApiImplNonNull ApiCLassFilter<T> filter, @ApiImplNonNull ApiImplCallback<Collection<Class<? extends T>>> callback);

    <T> Class<? extends T> getApi(@ApiImplNonNull Class<T> requiredType);

    <T> void getApi(@ApiImplNonNull Class<T> requiredType, @ApiImplNonNull ApiImplCallback<Class<? extends T>> callback);

    <T> Class<? extends T> getApi(@ApiImplNonNull Class<T> requiredType, long version);

    <T> void getApi(@ApiImplNonNull Class<T> requiredType, long version, @ApiImplNonNull ApiImplCallback<Class<? extends T>> callback);

    <T> Class<? extends T> getApi(@ApiImplNonNull Class<T> requiredType, String name);

    <T> void getApi(@ApiImplNonNull Class<T> requiredType, String name, @ApiImplNonNull ApiImplCallback<Class<? extends T>> callback);

    <T> Class<? extends T> getApi(@ApiImplNonNull Class<T> requiredType, String name, long version, boolean useRegex);

    <T> void getApi(@ApiImplNonNull Class<T> requiredType, String name, long version, boolean useRegex, @ApiImplNonNull ApiImplCallback<Class<? extends T>> callback);

    <T> void setImpl(@ApiImplNonNull Class<T> requiredType, String name, long version, T entity);

    <T> T getImpl(@ApiImplNonNull Class<T> requiredType);

    <T> void getImpl(@ApiImplNonNull Class<T> requiredType, @ApiImplNonNull ApiImplCallback<T> callback);

    <T> T getImpl(@ApiImplNonNull Class<T> requiredType, String name);

    <T> void getImpl(@ApiImplNonNull Class<T> requiredType, String name, @ApiImplNonNull ApiImplCallback<T> callback);

    <T> T getImpl(@ApiImplNonNull Class<T> requiredType, long version);

    <T> void getImpl(@ApiImplNonNull Class<T> requiredType, long version, @ApiImplNonNull ApiImplCallback<T> callback);

    <T> T getImpl(@ApiImplNonNull Class<T> requiredType, String name, long version, boolean useRegex);

    <T> void getImpl(@ApiImplNonNull Class<T> requiredType, String name, long version, boolean useRegex, @ApiImplNonNull ApiImplCallback<T> callback);

    <T> T hasApi(@ApiImplNonNull Class<T> requiredType, String name, long version);

    <T> T hasApi(@ApiImplNonNull Class<T> requiredType);

    <T> T newApi(@ApiImplNonNull Class<T> api);

    <T> T newApi(@ApiImplNonNull Class<T> api, String name);

    <T> T newApi(@ApiImplNonNull Class<T> api, String name, long version);

    @ApiImplNonNull
    String cachePut(@ApiImplNonNull Object data);

    @ApiImplNullable
    Object cacheGet(@ApiImplNonNull String key);

    @ApiImplNullable
    Object cacheRemove(@ApiImplNonNull String key);

    void setImplEnabled(@ApiImplNonNull String name, Boolean enable);

    Boolean getImplEnabled(@ApiImplNonNull String name);
}
